package live.hotel.dao.impl;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Iterator;
import java.util.List;

import live.common.Format;
import live.common.Page;
import live.hotel.dao.IXmlManage;
import live.hotel.entity.*;

import org.dom4j.Document;
import org.dom4j.Element;


@SuppressWarnings("unchecked")
public  class HotelPriceXml extends Page {
	private static final long serialVersionUID = 4988025692778099013L;
	private IXmlManage xmlMan = new XmlManage();
	private Document doc = null;
	private Format format = Format.getInstance();
	private List images = null;
	
	/**
	 * 获取酒店信息集合
	 * 
	 * @param page
	 * @param cityCode
	 * @param inDate
	 * @return
	 * @throws Exception
	 */
	public List<HotelInfo> getHotelPriceInfos(Page page, Search query)
			throws Exception {
		List<HotelInfo> infos = null;
		String strXml = resturnRequestXml(page, query);
		doc = xmlMan.getDataFromApi(strXml);
		if (doc != null) {
			super.setRecordCount(Integer.parseInt(doc.selectSingleNode(
					"//RecordCount").getText()));
			super.setPageIndex(page.getPageIndex());
			super.setPageSize(page.getPageSize());
			List hotelPrices = doc.selectNodes("//HotelDetails/*");
			Iterator iter = hotelPrices.iterator();
			infos = new ArrayList<HotelInfo>();
			Element e = null;
			HotelInfo info = null;
			while (iter.hasNext()) {
				e = (Element) iter.next();
				info = new HotelInfo();
				info.setCode(e.element("Item").attributeValue("Code").trim());
				info.setItem(e.elementTextTrim("Item").trim());
				info.setLocation(e.element("LocationDetails").elementTextTrim(
						"Location").trim());
				info.setAddress(e.elementTextTrim("Address").trim());
				info.setStarCode(e.element("StarRating").attributeValue("Code").trim()
						.substring(0, 1));
				info.setStarRating(e.elementTextTrim("StarRating").trim());
				info.setIntro(e.elementTextTrim("HotelIntro").trim());
				if (e.element("ImageLinks").element("ImageLink") != null) {
					info.setImgText(returnNodesList(e,".//Text"));
					info.setImages(returnNodesList(e, ".//Image"));
					info.setThumbNails(returnNodesList(e, ".//ThumbNail"));
				}
				info.setRooms(returnRooms(e, 0));
				infos.add(info);
			}
		}
		return infos;
	}
	
	/**
	 * 过滤出单个酒店价格列表信息
	 * @param page
	 * @param query
	 * @param code
	 * @return
	 * @throws Exception
	 */
	public HotelInfo getHotelPrice(Page page, Search query, String code)
			throws Exception {
		List<HotelInfo> infos = null;
		String strXml = resturnRequestXml(page, query);
		doc = xmlMan.getDataFromApi(strXml);
		HotelInfo info = null;
		if (doc != null) {
			super.setRecordCount(Integer.parseInt(doc.selectSingleNode(
					"//RecordCount").getText()));
			super.setPageIndex(page.getPageIndex());
			super.setPageSize(page.getPageSize());
			List hotelPrices = doc.selectNodes("//HotelDetails/*");
			Iterator iter = hotelPrices.iterator();
			infos = new ArrayList<HotelInfo>();
			Element e = null;
			String itemCode = null;
			while (iter.hasNext()) {
				e = (Element) iter.next();
				itemCode = e.element("Item").attributeValue("Code");
				if (itemCode.equals(code)) {
					info = new HotelInfo();
					info.setCode(itemCode);
					info.setItem(e.elementTextTrim("Item"));
					info.setLocation(e.element("LocationDetails")
							.elementTextTrim("Location"));
					info.setAddress(e.elementTextTrim("Address"));
					info.setStarCode(e.element("StarRating").attributeValue(
							"Code").substring(0, 1));
					info.setStarRating(e.elementTextTrim("StarRating"));
					info.setIntro(e.elementTextTrim("HotelIntro"));
					if (e.element("ImageLinks").element("ImageLink") != null) {
						info.setImgText(returnNodesList(e,".//Text"));
						info.setImages(returnNodesList(e, ".//Image"));
						info.setThumbNails(returnNodesList(e, ".//ThumbNail"));
					}
					info.setRooms(returnRooms(e, 0));
				}
			}
		}
		return info;
	}

	/**
	 * 获取房间信息集合
	 * 
	 * @param e
	 * @return
	 */
	public List<Room> returnRooms(Element e, int type) {
		List<Room> rooms = null;
		List<Room> nodes = e.selectNodes(".//Changed[@Code=0]/../../../../*");
		if (nodes.size() > 0) {
			rooms = new ArrayList<Room>();
			Iterator iterRoom = nodes.iterator();
			while (iterRoom.hasNext()) {
				Element el = (Element) iterRoom.next();
				Room room = new Room();
				room.setRoomType(el.elementTextTrim("RoomType"));
				room.setRoomCode(el.element("RoomType").attributeValue("Code"));
				room.setBedType(el.elementTextTrim("BedType"));
				room.setFloors(el.elementTextTrim("Floors"));
				room.setInternet(el.elementTextTrim("Internet"));
				room.setRoomArea(el.elementTextTrim("RoomArea"));
				room.setAddBed(el.elementTextTrim("AddBed"));
				room.setRoomDesc(el.elementTextTrim("RoomDesc"));
				room.setRates(returnRates(el, type));
				room.setAvailabilities(returnAvailabilitys(el));
				rooms.add(room);
			}
		}
		return rooms;
	}

	public List<Availability> returnAvailabilitys(Element e) {
		// System.out.println(e.asXML());
		List list = e.selectNodes(".//Availabilities/*");
		List<Availability> avails = null;
		if (list.size() > 0) {
			avails = new ArrayList<Availability>();
			Iterator iter = list.iterator();
			while (iter.hasNext()) {
				Element el = (Element) iter.next();
				// System.out.println(el.asXML());
				Availability item = new Availability();
				item.setDate(el.elementTextTrim("Date"));
				item.setStatus(Integer.parseInt(el.element("Status")
						.attributeValue("Code")));
				avails.add(item);
			}
		}
		return avails;
	}

	/**
	 * 房间价格信息集合
	 * 
	 * @param e
	 * @return
	 */
	public List<Rate> returnRates(Element e, int type) {
		List<Rate> rates = null;
		List<Rate> nodes = e.selectNodes(".//RoomQuatations/*");
		if (nodes.size() > 0) {
			rates = new ArrayList<Rate>();
			Iterator iterRate = nodes.iterator();
			while (iterRate.hasNext()) {
				Element el = (Element) iterRate.next();
				Rate rate = new Rate();
				rate.setDate(el.elementTextTrim("Date"));
				// [0:正常 | 1:有变价(屏蔽显示)]
				rate.setChange(el.element("Changed").attributeValue("Code"));
				rate.setDisplayPrice(Float.parseFloat(el
						.elementTextTrim("DisplayPrice")));
				rate.setSalePrice(Float.parseFloat(el
						.elementTextTrim("SalePrice")));
				rate.setBalsPrice(Float.parseFloat(el
						.elementTextTrim("BalsPrice")));
				rate.setPaymentType(format.isNotNullOrEmpty(el
						.elementTextTrim("PaymentType")) == true ? el
						.elementTextTrim("PaymentType").charAt(0) : ' ');
				rate.setBreakfast(el.elementTextTrim("Breakfast"));
				rate.setCommision(Float.parseFloat(el
						.elementTextTrim("Commision")));
				rate.setInternet(el.elementTextTrim("Internet"));
				rates.add(rate);
			}
		}
		return rates;
	}

	/**
	 * 图片集合
	 * 
	 * @param e
	 * @param xpath
	 * @return
	 */
	public List returnNodesList(Element e, String xpath) {
		List list = e.selectNodes(xpath);
		images = new ArrayList<String>();
		Iterator iter = list.iterator();
		for (int i = 0; i < list.size(); i++) {
			Element el = (Element) list.get(i);
			images.add(el.getText().trim());
		}
		return images;
	}

	/**
	 * 获取Page
	 * 
	 * @param page
	 * @param cityCode
	 * @param inDate
	 * @return
	 * @throws Exception
	 */
	public Page getPageInfo() throws Exception {
		return new Page(super.getPageIndex(), super.getRecordCount(),super.getTotalPage(), super
				.getPageSize());
	}

	public String resturnRequestXml(Page page, Search query) {
		StringBuffer buffer = new StringBuffer()
				.append("<SearchHotelPriceRequest>")
				.append("\n")
				.append("<Pager IsPager=\"true\">")
				.append("\n")
				.append("<PageIndex>").append(page.getPageIndex())
				.append("</PageIndex>").append("\n")
				.append("<PageSize>").append(page.getPageSize())
				.append("</PageSize>").append("\n")
				.append("</Pager>").append("\n")
				.append("<ItemDestination DestinationType=\"city\" DestinationCode=\"")
				.append(query.getCityCode().trim()).append("\" />")
				.append("\n").append("<PaymentType>T</PaymentType>")
				.append("\n").append("<ItemName>").append(query.getHotelItem()!=null?query.getHotelItem():"").append("</ItemName>").append("\n")
				.append("<PeriodOfStay>").append("\n")
				.append("<CheckInDate>").append(query.getCheckInDate().trim())
				.append("</CheckInDate>").append("\n")
				.append("<Duration>").append(returnDuration(query)).append("</Duration>").append("\n")
				.append("</PeriodOfStay>").append("\n").append("<StarRating>")
				.append(query.getStarCode() != null ? query.getStarCode().trim() : "").append("</StarRating>").append("\n")
				.append("<MinPrice>").append(query.getMinPrice() != 0L ? query.getMinPrice() : "").append("</MinPrice>").append("\n").
				append("<MaxPrice>").append(query.getMaxPrice() != 0L ? query.getMaxPrice() : "").append("</MaxPrice>").append("\n")
				.append("<RgnLocation>")
				.append(Format.getInstance().isNotNullOrEmpty(query.getRgnLocation())?query.getRgnLocation():"")
				.append("</RgnLocation>").append("\n")
				.append("<BsnLocation>")
				.append(Format.getInstance().isNotNullOrEmpty(query.getBsnLocation())?query.getBsnLocation():"")
				.append("</BsnLocation>").append("\n").append("</SearchHotelPriceRequest>").append("\n")
				.append("</RequestDetails>").append("\n").append("</Request>");
		return buffer.toString();
	}
	
	private int	returnDuration(Search search){
		String format="yyyy-MM-dd";
		Format formatPojo = Format.getInstance();
		Calendar calInDate = Calendar.getInstance();
		Calendar calOutDate = Calendar.getInstance();
		calInDate.setTime(formatPojo.stringToDate(search.getCheckInDate(), format));
		calOutDate.setTime(formatPojo.stringToDate(search.getCheckOutDate(), format));
		return calOutDate.get(Calendar.DAY_OF_YEAR)-calInDate.get(Calendar.DAY_OF_YEAR);
	}
}
